package org.jiucai.app;

import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.configuration.Configuration;
import org.jiucai.appframework.base.spring.dao.BaseDao;
import org.jiucai.appframework.base.util.ConfigUtil;
import org.jiucai.appframework.common.util.LogUtil;
import org.jiucai.appframework.common.util.Logs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.core.simple.SimpleJdbcOperations;

/**
 * 所有 dao 类的基类
 * 
 * @author zhaidw
 * 
 */
public abstract class AppBaseDao extends BaseDao {

	/**
	 * 被除数为0时，返回的除法计算结果
	 */
	public static final Integer ZERO_DIVISOR = -1000;

	/**
	 * 数据库允许的最大in的个数，oracle 是1000个，参考 ORA-01795: maximum number of expressions
	 * in a list is 1000
	 */
	public static final int MAX_IN_ALLOWED = 1000;

	protected static Logs logger = LogUtil.getLog(AppBaseDao.class);

	@Autowired
	protected DataSource dataSource;


	/**
	 * 获取查询数据的jdbc封装类
	 * 
	 * @return
	 */
	protected SimpleJdbcOperations getQueryDao() {

		return getSimpleJdbcTemplate();
	}

	/**
	 * 获取更新数据库数据的jdbc封装类
	 * 
	 * @return
	 */
	protected SimpleJdbcOperations getUpdateDao() {

		return getSimpleJdbcTemplate();
	}



	public SimpleJdbcCall getUpdateCall() {


		SimpleJdbcCall updateJdbcCall = new SimpleJdbcCall(dataSource);

		return updateJdbcCall;

	}

	/**
	 * 获取配置文件读取类
	 * 
	 * @return
	 */
	public Configuration getConfig() {

		return ConfigUtil.getConfiguration();
	}

	/**
	 * 获取in子句
	 * 
	 * @param columnName
	 *            字段名，可以包含表别名，最终会拼接到SQL中
	 * @param inValueList
	 *            in 参数中的值的列表
	 * @param parameters
	 *            MapSqlParameterSource 用来绑定参数
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected String getInClause(String columnName, List inValueList,
			MapSqlParameterSource parameters) {

		StringBuffer sql = new StringBuffer("");
		int campaignIdCount = 0;

		String columnNameParam = new StringBuffer(columnName).append("_param")
				.toString();

		if (null != inValueList && inValueList.size() > 0) {
			campaignIdCount = inValueList.size();

			log.debug(columnName + " values count : " + campaignIdCount);

			ArrayList detailIdList = null;

			sql.append(" and ( ");

			// 商
			int quotient = campaignIdCount / MAX_IN_ALLOWED;

			// 余数
			int remainder = campaignIdCount % MAX_IN_ALLOWED;

			// 不到最大值
			if (campaignIdCount <= MAX_IN_ALLOWED) {

				parameters.addValue(columnNameParam, inValueList);
				sql.append(" ").append(columnName).append(" in ( :")
						.append(columnNameParam).append(" ) ");

			} else {

				if (quotient > 0) {
					int count = 0;

					// 循环个数
					for (int i = 0; i < quotient; i++) {

						count = i * quotient;
						detailIdList = new ArrayList();

						for (int j = count; j < count + quotient; j++) {
							detailIdList.add(inValueList.get(j));
						}

						parameters.addValue(new StringBuffer(columnNameParam)
								.append(i).toString(), detailIdList);
						sql.append(" ").append(columnName).append(" in ( :")
								.append(columnNameParam).append(i)
								.append(" ) or ");
					}

				}

				if (remainder > 0) {

					detailIdList = new ArrayList();

					int count = quotient * MAX_IN_ALLOWED;

					for (int i = count; i < count + remainder; i++) {
						detailIdList.add(inValueList.get(i));
					}

					parameters.addValue(new StringBuffer(columnNameParam)
							.append(count).toString(), detailIdList);
					sql.append(" ").append(columnName).append(" in ( :")
							.append(columnNameParam).append(count)
							.append(" ) ");

				} else {
					sql.append(" 1=1 ");
				}

			}

			sql.append(" ) ");

		}

		// log.debug("in SQL: " + sql.toString() );

		return sql.toString();

	}
}
